'''
可以认为是针对模板容器ndarray开发的通用函数
ufuncs are used to implement vectorization in NumPy which is way faster than iterating over elements.
They also provide broadcasting and additional methods like reduce, accumulate etc. that are very helpful for computation.
ufuncs also take additional arguments, like:
where boolean array or condition defining where the operations should take place.
dtype defining the return type of elements.
out output array where the return value should be copied.
'''
import numpy as np

x = [1, 2, 3, 4]
y = [4, 5, 6, 7]
z = np.add(x, y)
print(z)
z = []
for i, j in zip(x, y):
  z.append(i + j)
print(z)

arr1 = np.array([10, 11, 12, 13, 14, 15])
arr2 = np.array([20, 21, 22, 23, 24, 25])
# +, -, *, /, **,%,div mod,abs
newarr = np.add(arr1, arr2) # 不用写foreach
print(newarr)
newarr = np.subtract(arr1, arr2)
print(newarr)
newarr = np.multiply(arr1, arr2)
print(newarr)
newarr = np.divide(arr1, arr2)#不是 a//b这种整除的方式
print(newarr)
arr1 = np.array([10, 11, 12, 13, 14, 15])
arr2 = np.array([2, 2, 2, 2, 2, 2])
newarr = np.power(arr1, arr2)
print(newarr)
newarr = np.mod(arr1, arr2) #remainder
print(newarr)
newarr = np.divmod(arr1, arr2) #div 和 mod的结果，两次一次计算
print(newarr)
arr = np.array([-1, -2, 1, 2, 3, -4])
newarr = np.absolute(arr)
print(newarr)

#三角函数 Trigonometric
arr = np.arange( 0,5 )
newarr = np.sin( arr )
print('np.sin( np.arange(0,5 ) ):',newarr)

#Hyperbolic Functions, 三角函数扩展的情况，表现为三角函数复合函数
print('np.sinh( np.arange(1,10 ) ):',np.sinh( np.arange(1,10 ) )) #sinh = 1/sin

#arc 反三角函数
print('np.arcsin( np.arange(0.1,1,0.1 ) ):',np.arcsin( np.arange(0.1,1,0.1 ) )) #arcsin,三角函数是超越函数
print('np.arctan( np.arange(1,10) ):',np.arctan( np.arange(1,10) )) #arcsin,三角函数是超越函数
#log 对数形式，通用的base 2，e，10，复杂的要用另外一种方式，不在列
print('np.log2( np.arange(1,10 ) ):',np.log2(np.arange(1, 10))) #base 2
print('np.log10( np.arange(1,10 ) ):',np.log10(np.arange(1, 10))) #base 10
print('np.log( np.arange(1,10 ) ):',np.log(np.arange(1, 10))) #base e

#Rounding Decimals
# 包括：truncation,fix,rounding,floor,ceil
arr = np.trunc([-3.1666, 3.6667])
print(arr)
arr = np.fix([-3.1666, 3.6667])
print(arr)
arr = np.around([-3.1666, 3.6667], 2)#后参数表示精度
print(arr)
arr = np.floor([-3.1666, 3.6667]) #正常也有个精度参数，居然没有
print(arr)
arr = np.ceil([-3.1666, 3.6667])
print(arr)

#Summations 累加
arr1 = np.array([1, 2, 3])
arr2 = np.array([1, 2, 3])
newarr = np.add(arr1, arr2) #默认column序列相加，返回的array的shape相同
print(newarr)
newarr = np.sum([arr1, arr2]) #逐项相加得到最终结果 nditer 取向累加
print(newarr)
newarr = np.sum([arr1, arr2],axis=1) #If you specify axis=1, NumPy will sum the numbers in each array.
print(newarr)
#Cummulative sum means partially adding the elements in array.
newarr = np.cumsum([arr1, arr2]) #If you specify axis=1, NumPy will sum the numbers in each array.
print(newarr)
newarr = np.cumsum([arr1, arr2],axis=1) #If you specify axis=1, NumPy will sum the numbers in each array.
print(newarr)

#Product 累乘，把sum 改成prod即可
arr1 = np.array([1, 2, 3])
arr2 = np.array([1, 2, 3])
newarr = np.prod(arr1)
print('np.prod([1, 2, 3])',newarr)
newarr = np.prod([arr1, arr2])
print('np.prod([[1, 2, 3],[1, 2, 3]])', newarr)
newarr = np.prod([arr1, arr2],axis=1) #If you specify axis=1, NumPy will sum the numbers in each array.
print('np.prod([[1, 2, 3],[1, 2, 3]],axis=1)',newarr)
#Cummulative prod means partially adding the elements in array.
newarr = np.cumprod([arr1, arr2]) #If you specify axis=1, NumPy will sum the numbers in each array.
print('np.cumprod([[1, 2, 3],[1, 2, 3]])',newarr)
newarr = np.cumprod([arr1, arr2],axis=1) #If you specify axis=1, NumPy will prod the numbers in each array.
print('np.cumprod([[1, 2, 3],[1, 2, 3]],axis=1)', newarr)

#Differences,array 逐项差值，n个项的数组，diff有n-1个
arr = np.array([10, 15, 25, 5])
newarr = np.diff(arr)
print("np.diff([10, 15, 25, 5]) :",newarr)
arr = np.array([10, 15, 25, 5])
newarr = np.diff(arr, n=2) #n表示做几次diff操作
print(newarr)

#gcd，最大公约数,注意这种下面带reduce的含义。
num1 = 4
num2 = 6
x = np.lcm(num1, num2)
print('np.lcm(4,6)',x)
print('np.gcd(4,6)',np.gcd(4,6))
arr = np.array([20, 8, 32, 36, 16])
x = np.gcd.reduce(arr)
print("np.gcd.reduce([20, 8, 32, 36, 16]) :",x) #所有项的公共最大公约数，a,b,c,d 的最大公约数，应该是gcd(gcd(gcd(a,b),c),d)
arr = np.array([3, 6, 9])
x = np.lcm.reduce(arr)
print("np.lcm.reduce([3, 6, 9]) :",x) #所有项的最小公倍数，lcm(lcm(a,b),c) 暴力的做法

## 以下内容来之 https://www.geeksforgeeks.org/numpy-ufunc/
